package stark.counter;

//计算器实现
public class counter {
    public static void main(String[] args) {
        String expression = "3+800*6-2";
        //创建两个栈 一个数栈 一个符号栈
        Arraystack2 numstack = new Arraystack2(10);
        Arraystack2 operstack = new Arraystack2(10);
        int index = 0;//用于扫描
        int oper = 0;
        int num1 = 0;
        int num2 = 0;
        char ch = ' ';//将每次扫描到的char保存到ch中
        String keepnum ="";
        //while语句开启扫描
        while (true){
            ch = expression.substring(index,index+1).charAt(0);//扫描字符，并为其转化为一个字符

            //判断ch是运算符还是数
            if(operstack.isoper(ch)){
                //如果是运算符
                if (!operstack.isEmpty()){
                    //不为空 进行比较
                    //判断当前符号栈是否为空 如果当前运算符优先级小于或等于栈中运算符，那么从数栈中pop两个数进行运算
                    if (operstack.priority(ch) <= operstack.priority(operstack.peek())){
                        num1 = numstack.pop();
                        num2 = numstack.pop();
                        oper = operstack.pop();
                        int res = numstack.cal(num1, num2, oper);
                        numstack.push(res);//将当前运算结果存入数栈
                        operstack.push(ch);

                    }else {//如果大于栈中操作符，则直接存入运算符栈
                        operstack.push(ch);
                    }

                }else {
                    //为空直接入栈
                    operstack.push(ch);
                }
            }else{//ch为数：直接入数栈  由于当前ch为字符 故‘1’=49 ‘2’=50 ‘3’=51.....

                //为了防止越界,需要判断ch是否是最后一位 若是 直接入栈
                if (index == expression.length()-1){
                    keepnum += ch;
                    numstack.push(Integer.parseInt(keepnum));
                }else{
                    //当发现ch为数时不能立刻入栈，必须判断下一个ch为符号是才可入栈  故定义一个字符串变量用于拼接
                    //处理多位数

                    keepnum += ch;

                    //如果下一个是数字继续扫描，如果不是就入数栈
                    if (operstack.isoper(expression.substring(index+1,index+2).charAt(0))){
                        numstack.push(Integer.parseInt(keepnum));
                        //!！注意keepnum需要清空
                        keepnum="";
                    }
                }

            }
            index++;//index + 1 并判断是否扫描完毕
            if (index >= expression.length()){

                break;
            }
        }
        //当扫描完毕后 就顺序从 数栈和符号栈中pop出相应的数和符号，并运行
        while (true){
            //如果符号栈为空，那么数栈只要一个数，其为结果
            if (operstack.isEmpty()){
                break;
            }else{
                num1 = numstack.pop();
                num2 = numstack.pop();
                oper = operstack.pop();
                int res = numstack.cal(num1, num2, oper);
                numstack.push(res);//将当前运算结果存入数栈
            }
        }
        System.out.println(numstack.pop());
    }

    static class Arraystack2 {//定义一个栈 扩展功能：
        private int maxsize; //栈
        private int[] stack; //数组 数组模拟栈
        private int top = -1; //top表示栈顶，初始化为-1


        public Arraystack2(int maxsize) {
            this.maxsize = maxsize;
            stack = new int[this.maxsize];
        }

        public boolean isFull() { //栈满
            return top == maxsize - 1;

        }

        public boolean isEmpty() { //栈空
            return top == -1;
        }

        public int peek() { //查看当前栈顶的符号或数值 但不取出

            return stack[top];
        }

        public void push(int value) { //入栈
            if (isFull()) {
                System.out.println("栈满");
                return;
            }
            top++;
            stack[top] = value;
        }

        public int pop() { //出栈
            if (isEmpty()) {
                throw new RuntimeException("栈空，没有数据");
            }

            int value = stack[top];
            top--;
            return value;
        }

        //显示栈的情况
        public void list() {
            if (isEmpty()) {
                System.out.println("栈空");

            }
            for (int i = top; i >= 0; i--) {
                System.out.println(stack[i]);

            }
        }

        //返回运算符的优先级 数字越大优先级越高
        public int priority(int oper) {
            if (oper == '*' || oper == '/'){
                return 1;
            }else if(oper == '+' || oper == '-'){
                return 0;
            }else {
                return -1;
            }

        }

        //判断是不是一个运算符
        public  boolean isoper(char value){
            return value=='+' || value=='-' || value=='*' || value=='/';
        }

        //计算方法
        public int cal(int num1,int num2,int oper){
            int res = 0;//存放运算结果
            switch (oper){
                case '+':
                    res=num1+num2;
                    break;
                case '-':
                    res=num2-num1;
                    break;
                case '*':
                    res=num1*num2;
                    break;
                case '/':
                    res=num2/num1;
                    break;
            }

            return res;
        }

    }
}
